package in.srain.cube.util;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import androidx.core.content.ContextCompat;
import android.telephony.TelephonyManager;
import android.text.TextUtils;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import in.srain.cube.cache.DiskFileUtils;
import in.srain.cube.request.JsonData;

public class DeviceInfoUtil {

    private static final String KEY_MIUI_VERSION_CODE = "ro.miui.ui.version.code";
    private static final String KEY_MIUI_VERSION_NAME = "ro.miui.ui.version.name";
    private static final String KEY_MIUI_INTERNAL_STORAGE = "ro.miui.internal.storage";
    private static final String CARRIER_OTHER = "其它";
    private static final Map<String, String> CARRIER_CACHE = new HashMap<>();

    static {
        CARRIER_CACHE.put("46000", "中国移动");
        CARRIER_CACHE.put("46002", "中国移动");
        CARRIER_CACHE.put("46007", "中国移动");
        CARRIER_CACHE.put("46008", "中国移动");
        CARRIER_CACHE.put("46001", "中国联通");
        CARRIER_CACHE.put("46006", "中国联通");
        CARRIER_CACHE.put("46009", "中国联通");
        CARRIER_CACHE.put("46010", "中国联通");
        CARRIER_CACHE.put("46003", "中国电信");
        CARRIER_CACHE.put("46005", "中国电信");
        CARRIER_CACHE.put("46011", "中国电信");
        CARRIER_CACHE.put("46004", "中国卫通");
        CARRIER_CACHE.put("46020", "中国铁通");
    }

    private static String sDeviceInfo = null;

    public static final String getDeviceInfo() {
        if (sDeviceInfo == null) {
            sDeviceInfo = String.format("%1$s_%2$s", Build.MODEL, Build.MANUFACTURER)
                    .replace("-", "__")
                    .replace(".", "_");
        }
        return sDeviceInfo;
    }

    public static boolean isMiUi() {
        //https://app.asana.com/0/50791733137488/155881026006851 ;Disable Xiaomi Push Notification
        // if (true) return false;

        String name = Build.MANUFACTURER;
        //可能存在风险
        if ("xiaomi".equalsIgnoreCase(name)) {
            return true;
        }

        try {
            final BuildProperties prop = BuildProperties.newInstance();
            return prop.getProperty(KEY_MIUI_VERSION_CODE, null) != null
                    || prop.getProperty(KEY_MIUI_VERSION_NAME, null) != null
                    || prop.getProperty(KEY_MIUI_INTERNAL_STORAGE, null) != null;
        } catch (final IOException e) {
            return false;
        }
    }

    public static boolean isHuaWei() {
        String name = Build.MANUFACTURER;

        if ("huawei".equalsIgnoreCase(name)) {
            return true;
        }

        return false;
    }

    public static String getName() {

        String buildVersion = "none";

        Class<?> classType = null;
        try {
            classType = Class.forName("android.os.SystemProperties");

            Method getMethod = classType.getDeclaredMethod("get", new Class<?>[]{String.class});
            buildVersion = (String) getMethod.invoke(classType, new Object[]{"ro.build.version.emui"});
        } catch (ClassNotFoundException e) {
        } catch (NoSuchMethodException e) {
        } catch (IllegalAccessException e) {
        } catch (InvocationTargetException e) {
        } catch (Exception e) {
        }

        return buildVersion;
    }

    public static boolean isEmotion() {
        String name = getName();

        if (name == null && name.length() == 0) {
            return false;
        }
        String lName = name.toLowerCase();

        if (lName.contains("emotion")) {
            return true;
        }

        return false;
    }

    public static boolean isTestPackage(Context app) {
        ApplicationInfo info = app.getApplicationInfo();
        String packageName = info.packageName;
        if ("co.s12e.one.dev".equals(packageName) || "co.s12e.one.stg".equals(packageName)) {
            return true;
        }
        return false;
    }

    public static boolean isHasPermission(Context context, String permission) {
        try {
            return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public static String getCarrier(Context context) {
        if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
            return CARRIER_OTHER;
        }
        if (context == null || !DeviceInfoUtil.isHasPermission(context, "android.permission.READ_PHONE_STATE")) {
            return CARRIER_OTHER;
        }

        try {
            final TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            if (telephonyManager == null) {
                return CARRIER_OTHER;
            }
            final String imsi = telephonyManager.getSubscriberId();
            return getCarrierByCode(context, imsi);
        } catch (Exception e) {
            e.printStackTrace();
            return CARRIER_OTHER;
        }
    }

    private static String getCarrierByCode(Context context, String code) {
        if (TextUtils.isEmpty(code)) {
            return CARRIER_OTHER;
        }

        String carrier = getCarrierFromCache(code);
        if (!TextUtils.isEmpty(carrier)) {
            return carrier;
        }

        carrier = getCarrierFromAssert(context, code);
        if (TextUtils.isEmpty(carrier)) {
            carrier = CARRIER_OTHER;
        }

        CARRIER_CACHE.put(code, carrier);
        return carrier;
    }

    private static String getCarrierFromCache(String code) {
        String carrier = CARRIER_CACHE.get(code);
        if (carrier != null) {
            return carrier;
        }

        for (Map.Entry<String, String> entry : CARRIER_CACHE.entrySet()) {
            if (code.startsWith(entry.getKey())) {
                return entry.getValue();
            }
        }
        return null;
    }

    private static String getCarrierFromAssert(Context context, String code) {
        final String jsonDataStr = DiskFileUtils.readAssert(context, "cp_mcc_mnc_mini.json");
        final JsonData carrierJsonData = JsonData.create(jsonDataStr);
        final int codeLength = code.length();
        String carrier = null;

        //mcc与mnc之和为5位数或6位数,6位数比较少，先截取6位数进行判断
        if (codeLength >= 6) {
            String mccMnc = code.substring(0, 6);
            carrier = carrierJsonData.optString(mccMnc);
        }
        if (TextUtils.isEmpty(carrier) && codeLength >= 5) {
            String mccMnc = code.substring(0, 5);
            carrier = carrierJsonData.optString(mccMnc);
        }
        return carrier;
    }
}